import Promise from 'promise';
import * as ResultMsg from '../constrants/ResultMsg';
import * as UserProxy from './user';
import * as TopicProxy from './topic';
import * as ReplyProxy from './reply';
import { MessageModel } from '../models';

export function count(appId, id, hasRead) {
  if (typeof appId !== 'string') throw new Error(ResultMsg.NO_APP_ID);
  if (typeof id !== 'string' && typeof id !== 'object') throw new Error(ResultMsg.NO_ID);
  if (typeof hasRead !== 'boolean') hasRead = false;
  return MessageModel.count({appId: appId, master_id: id, has_read: hasRead });
}

export async function find(appId, conditions, options) {
  if (typeof appId !== 'string') throw new Error(ResultMsg.NO_APP_ID);
  if (typeof conditions !== 'object') throw new Error(ResultMsg.NOT_OBJECT);
  if (typeof options !== 'object') options = null;
  conditions.appId = appId;

  try {
    const messages = await MessageModel.find(conditions).setOptions(options).exec();

    for (let i = 0; i < messages.length; i++) {
      let topic = null;
      let author = null;
      let reply = null;

      messages[i] = messages[i].toObject();

      if (messages[i].topic_id) {
        topic = await TopicProxy.findOneById(appId, messages[i].topic_id);
        messages[i].topic = topic;
      }

      if (messages[i].author_id) {
        author = await UserProxy.findOneById(appId, messages[i].author_id);
        messages[i].author = author;
      }

      if (messages[i].reply_id) {
        reply = await ReplyProxy.findOneById(appId, messages[i].reply_id);
        messages[i].reply = reply;
      }
    }

    return Promise.resolve(messages);
  } catch (err) {
    logger.error(err);
    return Promise.reject();
  }
}

export function findOneById(appId, id) {
  if (typeof appId !== 'string') throw new Error(ResultMsg.NO_APP_ID);
  if (typeof id !== 'string' && typeof id !== 'object') throw new Error(ResultMsg.NO_ID);
  return MessageModel.findOneById(id).exec();
}

export function findByUserId(appId, userId, hasRead, options) {
  if (typeof appId !== 'string') throw new Error(ResultMsg.NO_APP_ID);
  if (typeof userId !== 'string' && typeof userId !== 'object') throw new Error(ResultMsg.NO_ID);
  if (typeof hasRead !== 'boolean') hasRead = false
  if (typeof options !== 'object') options = null;
  return find(appId, { master_id: userId, has_read: hasRead }, options);
}

export function update(appId, id, data) {
  if (typeof appId !== 'string') throw new Error(ResultMsg.NO_APP_ID);
  if (typeof id !== 'string' && typeof id !== 'object') throw new Error(ResultMsg.NO_ID);
  if (typeof data !== 'object') throw new Error(ResultMsg.NOT_OBJECT);
  const query = MessageModel.findByIdAndUpdate(id, { $set: data });
  return query.exec();
}

export function create(appId, {type, masterId, authorId, topicId, replyId}) {
  if (typeof appId !== 'string') throw new Error(ResultMsg.NO_APP_ID);
  if (typeof type !== 'string') throw new Error(ResultMsg.NOT_STRING);
  if (typeof masterId !== 'string' && typeof masterId !== 'object') throw new Error(ResultMsg.NO_ID + masterId);
  if (typeof authorId !== 'string' && typeof authorId !== 'object') throw new Error(ResultMsg.NO_ID + authorId);
  if (typeof topicId !== 'string' && typeof topicId !== 'object') throw new Error(ResultMsg.NO_ID + topicId);
  if (typeof replyId !== 'string' && typeof replyId !== 'object') throw new Error(ResultMsg.NO_ID + replyId);
  const doc = new MessageModel();
  doc.appId = appId;
  doc.type = type;
  doc.master_id = masterId;
  doc.author_id = authorId;
  doc.topic_id = topicId;
  doc.reply_id = replyId;
  return doc.save();
}
